home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / ICProgKit 1.3.sit / ICProgKit1.3 / Internet Config Source / ICLinkIn.p < prev    next >
Text File  |  1996-08-24  |  51KB  |  1,683 lines

  1. unit ICLinkIn;
  2.  
  3. (* ・・・Start Header・・・ *)
  4.  
  5. (* File:         ICLinkIn.p}
  6. { * Generated by: 1.0d4}
  7. { * For:          IC 1.3}
  8. { * On:           Sunday, 14 July 1996, 20:19:55}
  9. { * }
  10. { * This file is part of the Internet Configuration system and}
  11. { * is placed in the public domain for the benefit of all.}
  12. { *)
  13.  
  14. (* ・・・End Header・・・ *)
  15.  
  16. interface
  17.  
  18.     uses
  19. {$ifc undefined THINK_Pascal}
  20.         Types, Files, QuickDraw, Aliases, 
  21. {$endc}
  22.         Components, ICTypes, ICKeys;
  23.  
  24.     type
  25.         ICRRecord = record                    (* this is *completely* private to the implementation!!! *)
  26.                 instance: ComponentInstance;        (* nil if no component available, if not nil then rest of record is junk *)
  27.                 have_config_file: boolean;
  28.                 config_file: FSSpec;
  29.                 config_refnum: integer;
  30.                 perm: ICPerm;
  31. {    inside_begin_XXXXXXX: boolean;}
  32.                 default_filename: Str63;
  33.                 prompt: Str255;
  34.             end;
  35.         ICRRecordPtr = ^ICRRecord;
  36.  
  37. (* ・・・Start ICRAPI.p・・・ *)
  38.  
  39.  
  40.   (* ***** Starting Up and Shutting Down ***** *)
  41.  
  42.     function ICRStart (var inst: ICRRecord; creator: OSType): ICError;
  43.     function ICRStop (var inst: ICRRecord): ICError;
  44.  
  45.   (* ***** Specifying a Configuration ***** *)
  46.  
  47.     function ICRFindConfigFile (var inst: ICRRecord; count: integer; folders: ICDirSpecArrayPtr): ICError;
  48.     function ICRFindUserConfigFile (var inst: ICRRecord; var where: ICDirSpec): ICError;
  49.     function ICRGeneralFindConfigFile (var inst: ICRRecord; search_prefs: Boolean; can_create: Boolean; count: integer; folders: ICDirSpecArrayPtr): ICError;
  50.     function ICRChooseConfig (var inst: ICRRecord): ICError;
  51.     function ICRChooseNewConfig (var inst: ICRRecord): ICError;
  52.     function ICRGetConfigName (var inst: ICRRecord; longname: Boolean; var name: Str255): ICError;
  53.     function ICRGetConfigReference (var inst: ICRRecord; ref: ICConfigRefHandle): ICError;
  54.     function ICRSetConfigReference (var inst: ICRRecord; ref: ICConfigRefHandle; flags: longint): ICError;
  55.     function ICRSpecifyConfigFile (var inst: ICRRecord; var config: FSSpec): ICError;
  56.  
  57.   (* ***** Getting Information ***** *)
  58.  
  59.     function ICRGetSeed (var inst: ICRRecord; var seed: longint): ICError;
  60.     function ICRGetPerm (var inst: ICRRecord; var perm: ICPerm): ICError;
  61.     function ICRDefaultFileName (var inst: ICRRecord; var name: Str63): ICError;
  62.  
  63.   (* ***** Reading and Writing Preferences ***** *)
  64.  
  65.     function ICRBegin (var inst: ICRRecord; perm: ICPerm): ICError;
  66.     function ICRGetPref (var inst: ICRRecord; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  67.     function ICRSetPref (var inst: ICRRecord; key: Str255; attr: ICAttr; buf: Ptr; size: longint): ICError;
  68.     function ICRFindPrefHandle (var inst: ICRRecord; key: Str255; var attr: ICAttr; prefh: Handle): ICError;
  69.     function ICRGetPrefHandle (var inst: ICRRecord; key: Str255; var attr: ICAttr; var prefh: Handle): ICError;
  70.     function ICRSetPrefHandle (var inst: ICRRecord; key: Str255; attr: ICAttr; prefh: Handle): ICError;
  71.     function ICRCountPref (var inst: ICRRecord; var count: longint): ICError;
  72.     function ICRGetIndPref (var inst: ICRRecord; n: longint; var key: Str255): ICError;
  73.     function ICRDeletePref (var inst: ICRRecord; key: Str255): ICError;
  74.     function ICREnd (var inst: ICRRecord): ICError;
  75.  
  76.   (* ***** User Interface Stuff ***** *)
  77.  
  78.     function ICREditPreferences (var inst: ICRRecord; key: Str255): ICError;
  79.  
  80.   (* ***** URL Handling ***** *)
  81.  
  82.     function ICRParseURL (var inst: ICRRecord; hint: Str255; data: Ptr; len: longint; var selStart: longint; var selEnd: longint; url: Handle): ICError;
  83.     function ICRLaunchURL (var inst: ICRRecord; hint: Str255; data: Ptr; len: longint; var selStart: longint; var selEnd: longint): ICError;
  84.  
  85.   (* ***** Mappings Routines *****}
  86. {   * }
  87. {   * Routines for interrogating mappings database.}
  88. {   * }
  89. {   * ----- High Level Routines -----}
  90. {   *)
  91.  
  92.     function ICRMapFilename (var inst: ICRRecord; filename: Str255; var entry: ICMapEntry): ICError;
  93.     function ICRMapTypeCreator (var inst: ICRRecord; fType: OSType; fCreator: OSType; filename: Str255; var entry: ICMapEntry): ICError;
  94.  
  95.   (* ----- Mid Level Routines ----- *)
  96.  
  97.     function ICRMapEntriesFilename (var inst: ICRRecord; entries: Handle; filename: Str255; var entry: ICMapEntry): ICError;
  98.     function ICRMapEntriesTypeCreator (var inst: ICRRecord; entries: Handle; fType: OSType; fCreator: OSType; filename: Str255; var entry: ICMapEntry): ICError;
  99.  
  100.   (* ----- Low Level Routines ----- *)
  101.  
  102.     function ICRCountMapEntries (var inst: ICRRecord; entries: Handle; var count: longint): ICError;
  103.     function ICRGetIndMapEntry (var inst: ICRRecord; entries: Handle; ndx: longint; var pos: longint; var entry: ICMapEntry): ICError;
  104.     function ICRGetMapEntry (var inst: ICRRecord; entries: Handle; pos: longint; var entry: ICMapEntry): ICError;
  105.     function ICRSetMapEntry (var inst: ICRRecord; entries: Handle; pos: longint; var entry: ICMapEntry): ICError;
  106.     function ICRDeleteMapEntry (var inst: ICRRecord; entries: Handle; pos: longint): ICError;
  107.     function ICRAddMapEntry (var inst: ICRRecord; entries: Handle; var entry: ICMapEntry): ICError;
  108.  
  109. (* ・・・End ICRAPI.p・・・ *)
  110.  
  111. implementation
  112.  
  113.     uses
  114. {$ifc undefined THINK_Pascal}
  115.         Resources, GestaltEqu, OSUtils, Memory, ToolUtils, Packages, StandardFile, 
  116. {$endc}
  117.         AppleTalk, Folders, Processes, Errors, AppleEvents, 
  118.  
  119.         ICLinkInSubs;
  120.  
  121.  
  122.     function ICFindFolder (vRefNum: integer; folderType: OSType; createFolder: boolean; var foundVRefNum: integer; var foundDirID: longint): OSErr;
  123.     inline
  124.         $7000, $A823;
  125.  
  126.     const
  127.         kICOurManufacturer = 'JPQE';
  128.         Res_Code = 'ICRP';
  129.  
  130.     function ICRStart (var inst: ICRRecord; creator: OSType): ICError;
  131.         var
  132.             junk: ICError;
  133.     begin
  134.         inst.have_config_file := false;
  135.         inst.config_file.vRefNum := 0;
  136.         inst.config_file.parID := 0;
  137.         inst.config_file.name := '';
  138.         inst.config_refnum := 0;
  139.         inst.perm := icNoPerm;
  140.         inst.prompt := 'Create configuration as:';
  141.         junk := ICRDefaultFileName(inst, inst.default_filename);
  142.         ICRStart := noErr;
  143.     end; (* ICRStart *)
  144.  
  145.     function ICRCloseIfOpen (var inst: ICRRecord): Boolean;
  146.     begin
  147.         ICRCloseIfOpen := inst.perm <> icNoPerm;
  148.         if inst.config_refnum <> 0 then begin
  149.             CloseResFile(inst.config_refnum);
  150.             inst.config_refnum := 0;
  151.         end; (* if *)
  152.         inst.perm := icNoPerm;
  153.     end; (* ICRCloseIfOpen *)
  154.  
  155.     function ICRStop (var inst: ICRRecord): ICError;
  156.         var
  157.             err: OSErr;
  158.     begin
  159.         if ICRCloseIfOpen(inst) then begin
  160.             err := paramErr;
  161.         end
  162.         else begin
  163.             err := noErr;
  164.         end;
  165.         ICRStop := err;
  166.     end; (* ICRStop *)
  167.  
  168.     function ValidDirSpec (folder: ICDirSpec): ICError;
  169.         var
  170.             cpb: CInfoPBRec;
  171.     begin
  172.         cpb.ioVRefNum := folder.vRefNum;
  173.         cpb.ioDirID := folder.dirID;
  174.         cpb.ioNamePtr := nil;
  175.         cpb.ioFDirIndex := -1;
  176.         ValidDirSpec := PBGetCatInfoSync(@cpb);
  177.     end; (* ValidDirSpec *)
  178.  
  179.     function ScanFolder (var inst: ICRRecord; folder: ICDirSpec; var found_file: FSSpec): boolean;
  180.  
  181.         function FoundFile (folder: ICDirSpec; ndx: integer; var found_file: FSSpec): OSErr;
  182.             var
  183.                 err: OSErr;
  184.                 cpb: CInfoPBRec;
  185.                 is_folder: boolean;
  186.                 was_alias: boolean;
  187.                 response: longint;
  188.         begin
  189.             with cpb do begin (* safe *)
  190.                 ioVRefNum := folder.vRefNum;
  191.                 ioDirID := folder.dirID;
  192.                 ioNamePtr := @found_file.name;
  193.                 ioFDirIndex := ndx;
  194.                 err := PBGetCatInfoSync(@cpb);
  195.                 if err = noErr then begin
  196.                     found_file.vRefNum := cpb.ioVRefNum;
  197.                     found_file.parID := cpb.ioFlParID;
  198.                     if (btst(cpb.ioFlAttrib, 4) or (cpb.ioFlFndrInfo.fdType <> ICfiletype)) then begin
  199.                         err := 1;
  200.                     end
  201.                     else if (Gestalt(gestaltAliasMgrAttr, response) = noErr) & btst(response, gestaltAliasMgrPresent) then begin
  202.                         err := ResolveAliasFile(found_file, true, is_folder, was_alias);
  203.                         if err <> noErr then begin
  204.                             err := 1;
  205.                         end; (* if *)
  206.                     end; (* if *)
  207.                 end; (* if *)
  208.             end; (* with *)
  209.             FoundFile := err;
  210.         end; (* FoundFile *)
  211.  
  212.         var
  213.             err: ICError;
  214.             found: boolean;
  215.             i: integer;
  216.     begin
  217.         found_file.name := (inst.default_filename);
  218.         found := (FoundFile(folder, 0, found_file) = noErr);
  219.         if not found then begin
  220.             i := 1;
  221.             repeat
  222.                 found_file.name := '';
  223.                 err := FoundFile(folder, i, found_file);
  224.                 i := i + 1;
  225.             until err <> 1;
  226.             found := (err = noErr);
  227.         end; (* if *)
  228.         ScanFolder := found;
  229.     end; (* ScanFolder *)
  230.  
  231.     function ICRFindConfigFile (var inst: ICRRecord; count: integer; folders: ICDirSpecArrayPtr): ICError;
  232.     begin
  233.         ICRFindConfigFile := ICRGeneralFindConfigFile(inst, true, true, count, folders);
  234.     end; (* ICRFindConfigFile *)
  235.  
  236.     function ICRFindUserConfigFile (var inst: ICRRecord; var where: ICDirSpec): ICError;
  237.     begin
  238.         ICRFindUserConfigFile := ICRGeneralFindConfigFile(inst, false, true, 1, @where);
  239.     end; (* ICRFindUserConfigFile *)
  240.  
  241.     function ICRGeneralFindConfigFile (var inst: ICRRecord; search_prefs: Boolean; can_create: Boolean; count: integer; folders: ICDirSpecArrayPtr): ICError;
  242.  
  243.         function FindPrefFolder (var pref_fold: ICDirSpec): OSErr;
  244.             var
  245.                 err: OSErr;
  246.                 env: SysEnvRec;
  247.                 junk: longint;
  248.                 response: longint;
  249.         begin
  250.             if (Gestalt(gestaltFindFolderAttr, response) = noErr) & btst(response, gestaltFindFolderPresent) then begin
  251.                 (* Gestalt says it's implemented -- call it directly *)
  252.                 err := ICFindFolder(kOnSystemDisk, kPreferencesFolderType, true, pref_fold.vRefNum, pref_fold.dirID);
  253.             end
  254.             else begin
  255.                 (* Simulate the important stuff *)
  256.                 err := SysEnvirons(curSysEnvVers, env);
  257.                 if err = noErr then begin
  258.                     err := GetWDInfo(env.sysVRefNum, pref_fold.vRefNum, pref_fold.dirID, junk);
  259.                 end; (* if *)
  260.             end; (* if *)
  261.             FindPrefFolder := err;
  262.         end; (* FindPrefFolder *)
  263.  
  264.         var
  265.             err: ICError;
  266.             i: integer;
  267.             found: boolean;
  268.             pref_fold: ICDirSpec;
  269.             last_folder_scanned: ICDirSpec;
  270.             temp_config_file: FSSpec;
  271.     begin
  272.         err := noErr;
  273.         if (err = noErr) & (inst.perm <> icNoPerm) then begin
  274.             err := paramErr;
  275.         end;
  276.         if (err = noErr) & (count < 0) | ((count <> 0) & (folders = nil)) then begin
  277.             err := paramErr;
  278.         end; (* if *)
  279.         if (err = noErr) & (count = 0) & not search_prefs & can_create then begin
  280.             err := paramErr;
  281.         end;
  282.         i := 0;
  283.         while (err = noErr) & (i < count) do begin
  284.             err := ValidDirSpec(folders^[i]);
  285.             i := i + 1;
  286.         end; (* for *)
  287.         if err = noErr then begin
  288.             i := 0;
  289.             found := false;
  290.             while (i < count) and not found do begin
  291.                 found := ScanFolder(inst, folders^[i], temp_config_file);
  292.                 last_folder_scanned := folders^[i];
  293.                 i := i + 1;
  294.             end; (* while *)
  295.             if not found & search_prefs then begin
  296.                 err := FindPrefFolder(pref_fold);
  297.                 if (err = noErr) then begin
  298.                     found := ScanFolder(inst, pref_fold, temp_config_file);
  299.                     last_folder_scanned := pref_fold;
  300.                 end;
  301.             end; (* if *)
  302.             if not found and can_create then begin
  303.                 temp_config_file.vRefNum := last_folder_scanned.vRefNum;
  304.                 temp_config_file.parID := last_folder_scanned.dirID;
  305.                 temp_config_file.name := inst.default_filename;
  306.                 found := true;
  307.             end; (* if *)
  308.             if not found then begin
  309.                 err := icConfigNotFoundErr;
  310.             end;
  311.         end; (* if *)
  312.         if err = noErr then begin
  313.             inst.config_file := temp_config_file;
  314.         end;
  315.         inst.have_config_file := (err = noErr);
  316.         ICRGeneralFindConfigFile := err;
  317.     end; (* ICRGeneralFindConfigFile *)
  318.  
  319.     procedure SetSFCWD (var inst: ICRRecord);
  320.         const
  321.             CurDirStore = $398;
  322.             SFSaveDisk = $214;
  323.         type
  324.             longPtr = ^longInt;
  325.             intPtr = ^integer;
  326.     begin
  327.         if inst.have_config_file then begin
  328.             longPtr(CurDirStore)^ := inst.config_file.parID;
  329.             intPtr(SFSaveDisk)^ := -inst.config_file.vRefNum;
  330.         end;
  331.     end;
  332.  
  333.     function GetFile (var inst: ICRRecord; var fs: FSSpec): ICError;
  334.         var
  335.             err: ICError;
  336.             typeList: SFTypeList;
  337.             nreply: StandardFileReply;
  338.             oreply: SFReply;
  339.             eric: longInt;
  340.     begin
  341.         SetSFCWD(inst);
  342.         err := userCanceledErr;
  343.         typeList[0] := ICfiletype;
  344.         if ICUHaveNewStandardFile then begin
  345.             StandardGetFile(nil, 1, typeList, nreply);
  346.             if nreply.sfGood then begin
  347.                 fs := nreply.sfFile;
  348.                 err := noErr;
  349.             end;
  350.         end
  351.         else begin
  352.             SFGetFile(Point($4040), '', nil, 1, typeList, nil, oreply);
  353.             if oreply.good then begin
  354.                 err := GetWDInfo(oreply.vRefNum, fs.vRefNum, fs.parID, eric);
  355.                 fs.name := oreply.fName;
  356.             end;
  357.         end;
  358.         GetFile := err;
  359.     end;
  360.  
  361.     function PutFile (var inst: ICRRecord; var fs: FSSpec): ICError;
  362.         var
  363.             err: ICError;
  364.             typeList: SFTypeList;
  365.             nreply: StandardFileReply;
  366.             oreply: SFReply;
  367.             eric: longInt;
  368.             defname: Str63;
  369.     begin
  370.         SetSFCWD(inst);
  371.         err := userCanceledErr;
  372.         typeList[0] := ICfiletype;
  373.         if inst.have_config_file then begin
  374.             defname := inst.config_file.name;
  375.         end
  376.         else begin
  377.             defname := inst.default_filename;
  378.         end;
  379.         if ICUHaveNewStandardFile then begin
  380.             StandardPutFile(inst.prompt, defname, nreply);
  381.             if nreply.sfGood then begin
  382.                 fs := nreply.sfFile;
  383.                 err := noErr;
  384.             end;
  385.         end
  386.         else begin
  387.             SFPutFile(Point($4040), inst.prompt, defname, nil, oreply);
  388.             if oreply.good then begin
  389.                 err := GetWDInfo(oreply.vRefNum, fs.vRefNum, fs.parID, eric);
  390.                 fs.name := oreply.fName;
  391.             end;
  392.         end;
  393.         PutFile := err;
  394.     end;
  395.  
  396.     function ICRChooseConfig (var inst: ICRRecord): ICError;
  397.         var
  398.             err: OSErr;
  399.             config: FSSpec;
  400.     begin
  401.         err := noErr;
  402.         if (err = noErr) & (inst.perm <> icNoPerm) then begin
  403.             err := paramErr;
  404.         end;
  405.         if err = noErr then begin
  406.             err := ICUCanInteract;
  407.         end;
  408.         if err = noErr then begin
  409.             err := GetFile(inst, config);
  410.         end;
  411.         if err = noErr then begin
  412.             err := ICRSpecifyConfigFile(inst, config);
  413.         end;
  414.         ICRChooseConfig := err;
  415.     end;
  416.  
  417.     function ICRChooseNewConfig (var inst: ICRRecord): ICError;
  418.         var
  419.             err, junk: OSErr;
  420.             config: FSSpec;
  421.     begin
  422.         err := noErr;
  423.         if (err = noErr) & (inst.perm <> icNoPerm) then begin
  424.             err := paramErr;
  425.         end;
  426.         if err = noErr then begin
  427.             err := ICUCanInteract;
  428.         end;
  429.         if err = noErr then begin
  430.             err := PutFile(inst, config);
  431.         end;
  432.         if err = noErr then begin
  433.             junk := HDelete(config.vRefNum, config.parID, config.name);
  434.             err := HCreate(config.vRefNum, config.parID, config.name, ICcreator, ICfiletype);
  435.         end;
  436.         if err = noErr then begin
  437.             err := ICRSpecifyConfigFile(inst, config);
  438.         end;
  439.         ICRChooseNewConfig := err;
  440.     end;
  441.  
  442.     function ICRGetConfigName (var inst: ICRRecord; longname: Boolean; var name: Str255): ICError;
  443.         var
  444.             err: OSErr;
  445.     begin
  446.         err := noErr;
  447.         if (err = noErr) & not inst.have_config_file then begin
  448.             err := paramErr;
  449.         end;
  450.         if not longname then begin
  451.             name := inst.config_file.name;
  452.             err := noErr;
  453.         end
  454.         else begin
  455.             err := ICUFSSPecToFullPath(inst.config_file, name);
  456.         end;
  457.         ICRGetConfigName := err;
  458.     end;
  459.  
  460.     function ICRGetConfigReference (var inst: ICRRecord; ref: ICConfigRefHandle): ICError;
  461.         var
  462.             err: ICError;
  463.             header: ICConfigRef;
  464.             loe: longint;
  465.     begin
  466.         err := noErr;
  467.         if (err = noErr) & not inst.have_config_file then begin
  468.             err := paramErr;
  469.         end;
  470.         if (err = noErr) & (ref = nil) then begin
  471.             err := paramErr;
  472.         end;
  473.         if err = noErr then begin
  474.             err := FSSpecToICFileSpec(inst.config_file, ICFileSpecHandle(ref));
  475.         end;
  476.         if err = noErr then begin
  477.             header.manufacturer := kICOurManufacturer;
  478.             loe := Munger(Handle(ref), 0, nil, 0, @header, SizeOf(header));
  479.             err := MemError;
  480.         end;
  481.         if err <> noErr then begin
  482.             SetHandleSize(Handle(ref), 0);
  483.         end;
  484.         ICRGetConfigReference := err;
  485.     end;
  486.  
  487.     function ICRSetConfigReference (var inst: ICRRecord; ref: ICConfigRefHandle; flags: longint): ICError;
  488.         var
  489.             err: ICError;
  490.             filespec: ICFileSpecHandle;
  491.             loe: longInt;
  492.             fs: FSSpec;
  493.     begin
  494.         err := noErr;
  495.         if (err = noErr) & (inst.perm <> icNoPerm) then begin
  496.             err := paramErr;
  497.         end;
  498.         if (err = noErr) & (ref = nil) then begin
  499.             err := paramErr;
  500.         end;
  501.         if (err = noErr) & (GetHandleSize(Handle(ref)) < 4) then begin
  502.             err := paramErr;
  503.         end;
  504.         if (err = noErr) & (ref^^.manufacturer <> kICOurManufacturer) then begin
  505.             err := icConfigInappropriateErr;
  506.         end;
  507.         if (err = noErr) & (GetHandleSize(Handle(ref)) < SizeOf(ICConfigRef) + SizeOf(ICFileSpec)) then begin
  508.             err := paramErr;
  509.         end;
  510.         if (err = noErr) then begin
  511.             filespec := ICFileSpecHandle(ref);
  512.             err := HandToHand(Handle(filespec));
  513.             if err = noErr then begin
  514.                 loe := Munger(Handle(filespec), 0, nil, SizeOf(ICConfigRef), @loe, 0);
  515.                 err := ICFileSpecToFSSpec(filespec, not BTST(flags, icNoUserInteraction_bit), fs);
  516.                 if err = fnfErr then begin
  517.                     err := noErr;
  518.                 end;
  519.                 DisposeHandle(Handle(filespec));
  520.             end;
  521.         end;
  522.         if err = noErr then begin
  523.             err := ICRSpecifyConfigFile(inst, fs);
  524.         end;
  525.         ICRSetConfigReference := err;
  526.     end;
  527.  
  528.     function ICRSpecifyConfigFile (var inst: ICRRecord; var config: FSSpec): ICError;
  529.         var
  530.             err: ICError;
  531.             folder: ICDirSpec;
  532.     begin
  533.         err := noErr;
  534.         if (err = noErr) & (inst.perm <> icNoPerm) then begin
  535.             err := paramErr;
  536.         end;
  537.         if err = noErr then begin
  538.             folder.vRefNum := config.vRefNum;
  539.             folder.dirID := config.parID;
  540.             err := ValidDirSpec(folder);
  541.             if err = noErr then begin
  542.                 inst.config_file := config;
  543.             end; (* if *)
  544.             inst.have_config_file := (err = noErr);
  545.         end;
  546.         ICRSpecifyConfigFile := err;
  547.     end; (* ICRSpecifyConfigFile *)
  548.  
  549.     function ICRGetSeed (var inst: ICRRecord; var seed: longint): ICError;
  550.         var
  551.             err: ICError;
  552.             cpb: CInfoPBRec;
  553.     begin
  554.         seed := 0;
  555.         err := fnfErr;
  556.         if inst.have_config_file then begin
  557.             with cpb do begin (* safe *)
  558.                 ioVRefNum := inst.config_file.vRefNum;
  559.                 ioDirID := inst.config_file.parID;
  560.                 ioNamePtr := @inst.config_file.name;
  561.                 ioFDirIndex := 0;
  562.             end; (* with *)
  563.             err := PBGetCatInfoSync(@cpb);
  564.             if err = noErr then begin
  565.                 seed := cpb.ioFlMdDat;
  566.             end
  567.             else if err = fnfErr then begin
  568.                 err := noErr;
  569.             end; (* if *)
  570.         end; (* if *)
  571.         ICRGetSeed := err;
  572.     end; (* ICRGetSeed *)
  573.  
  574.     function ICRGetPerm (var inst: ICRRecord; var perm: ICPerm): ICError;
  575.     begin
  576.         perm := inst.perm;
  577.         ICRGetPerm := noErr;
  578.     end; (* ICRGetPerm *)
  579.  
  580.     function ICRPermToFSPerm (perm: ICPerm): integer;
  581.     begin
  582.         case perm of
  583.             icReadOnlyPerm: 
  584.                 ICRPermToFSPerm := fsRdPerm;
  585.             icReadWritePerm: 
  586.                 ICRPermToFSPerm := fsRdWrPerm;
  587.             otherwise
  588.                 ICRPermToFSPerm := 0;
  589.         end; (* case *)
  590.     end; (* ICRPermToFSPerm *)
  591.  
  592.     function ICRBegin (var inst: ICRRecord; perm: ICPerm): ICError;
  593.         var
  594.             err: ICError;
  595.             ref: integer;
  596.             junk: OSErr;
  597.     begin
  598.         err := noErr;
  599.         if (inst.perm <> icNoPerm) or (perm = icNoPerm) then begin
  600.             err := paramErr;
  601.         end; (* if *)
  602.         if err = noErr then begin
  603.             if not inst.have_config_file then begin
  604.                 err := bdNamErr;
  605.             end; (* if *)
  606.         end; (* if *)
  607.         if err = noErr then begin
  608.             ref := HOpenResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICRPermToFSPerm(perm));
  609.             err := ResError;
  610.             if (err = fnfErr) or (err = eofErr) then begin
  611.                 case perm of
  612.                     icReadOnlyPerm:  begin
  613.                         ref := 0;
  614.                         err := noErr;
  615.                     end; (* icReadOnlyPerm *)
  616.                     icReadWritePerm:  begin
  617.                         junk := HCreate(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICcreator, ICfiletype);
  618.                         HCreateResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name);
  619.                         ref := HOpenResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICRPermToFSPerm(perm));
  620.                         err := ResError;
  621.                     end; (* icReadWritePerm *)
  622.                 end; (* case *)
  623.             end; (* if *)
  624.         end; (* if *)
  625.         if err = noErr then begin
  626.             inst.config_refnum := ref;
  627.             inst.perm := perm;
  628.         end; (* if *)
  629.         case err of
  630.             opWrErr, permErr: 
  631.                 err := icNoMoreWritersErr;
  632.             otherwise { do nothing }
  633.         end; (* case *)
  634.         ICRBegin := err;
  635.     end; (* ICRBegin *)
  636.  
  637.     function ICRCheckInside (var inst: ICRRecord): ICError;
  638.     begin
  639.         if inst.perm = icNoPerm then begin
  640.             ICRCheckInside := paramErr;
  641.         end
  642.         else begin
  643.             ICRCheckInside := noErr;
  644.         end; (* if *)
  645.     end; (* ICRCheckInside *)
  646.  
  647.     function ICRForceInside (var inst: ICRRecord; perm: ICPerm; var force_info: boolean): ICError;
  648.         var
  649.             err: ICError;
  650.     begin
  651.         force_info := false;
  652.         if (inst.perm = perm) or ((inst.perm = icReadWritePerm) and (perm = icReadOnlyPerm)) then begin
  653.             err := noErr;
  654.         end
  655.         else if inst.perm = icNoPerm then begin
  656.             err := ICRBegin(inst, perm);
  657.             force_info := (err = noErr);
  658.         end
  659.         else begin
  660.             err := icPermErr;
  661.         end; (* if *)
  662.         ICRForceInside := err;
  663.     end; (* ICRForceInside *)
  664.  
  665.     function ICRReleaseInside (var inst: ICRRecord; force_info: boolean): ICError;
  666.     begin
  667.         if force_info then begin
  668.             ICRReleaseInside := ICREnd(inst);
  669.         end
  670.         else begin
  671.             ICRReleaseInside := noErr;
  672.         end; (* if *)
  673.     end; (* ICRReleaseInside *)
  674.  
  675.     function ICRGetPref (var inst: ICRRecord; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  676.         var
  677.             err: ICError;
  678.             err2: ICError;
  679.             max_size: longint;
  680.             true_size: longint;
  681.             old_refnum: integer;
  682.             prefh: Handle;
  683.             force_info: boolean;
  684.     begin
  685.         max_size := size;
  686.         size := 0;
  687.         attr := ICattr_no_change;
  688.         prefh := nil;
  689.         err := ICRForceInside(inst, icReadOnlyPerm, force_info);
  690.         if (err = noErr) and (inst.config_refnum = 0) then begin
  691.             err := icPrefNotFoundErr;
  692.         end; (* if *)
  693.         if (err = noErr) and ((key = '') or ((max_size < 0) and (buf <> nil))) then begin
  694.             err := paramErr;
  695.         end; (* if *)
  696.         if err = noErr then begin
  697.             old_refnum := CurResFile;
  698.             UseResFile(inst.config_refnum);
  699.             err := ResError;
  700.             if err = noErr then begin
  701.                 prefh := Get1NamedResource(Res_Code, key);
  702.                 err := ResError;
  703.                 if prefh = nil then begin
  704.                     err := icPrefNotFoundErr;
  705.                 end; (* if *)
  706.                 if err = noErr then begin
  707.                     true_size := GetHandleSize(prefh);
  708.                     if true_size < 4 then begin
  709.                         err := icPrefDataErr;
  710.                     end; (* if *)
  711.                 end; (* if *)
  712.                 if err = noErr then begin
  713.                     size := true_size - 4;
  714.                     attr := longintPtr(prefh^)^;
  715.                     if (buf <> nil) and (size <> 0) then begin
  716.                         if size > max_size then begin
  717.                             err := icTruncatedErr;
  718.                         end
  719.                         else begin
  720.                             max_size := size;
  721.                         end; (* if *)
  722.                         BlockMove(ptr(longint(prefh^) + 4), buf, max_size);
  723.                     end; (* if *)
  724.                 end; (* if *)
  725.                 UseResFile(old_refnum);
  726.             end; (* if *)
  727.         end; (* if *)
  728.         if prefh <> nil then begin
  729.             ReleaseResource(prefh);
  730.         end; (* if *)
  731.         err2 := ICRReleaseInside(inst, force_info);
  732.         if err = noErr then begin
  733.             err := err2;
  734.         end; (* if *)
  735.         ICRGetPref := err;
  736.     end; (* ICRGetPref *)
  737.  
  738.     function ICRSetPref (var inst: ICRRecord; key: Str255; attr: ICAttr; buf: Ptr; size: longint): ICError;
  739.         var
  740.             err: ICError;
  741.             err2: ICError;
  742.             old_attr: longint;
  743.             old_refnum: integer;
  744.             prefh: Handle;
  745.             id: integer;
  746.             force_info: boolean;
  747.     begin
  748.         prefh := nil;
  749.         if buf = nil then begin
  750.             size := 0;
  751.         end;
  752.         err := ICRForceInside(inst, icReadWritePerm, force_info);
  753.         if (err = noErr) and (inst.perm <> icReadWritePerm) then begin
  754.             err := icPermErr;
  755.         end; (* if *)
  756.         if (err = noErr) and (inst.config_refnum = 0) then begin
  757.             err := icInternalErr;
  758.         end; (* if *)
  759.         if (err = noErr) and ((key = '') or (size < 0)) then begin
  760.             err := paramErr;
  761.         end; (* if *)
  762.         if err = noErr then begin
  763.             old_refnum := CurResFile;
  764.             UseResFile(inst.config_refnum);
  765.             err := ResError;
  766.             if err = noErr then begin
  767.                 prefh := Get1NamedResource(Res_Code, key);
  768.                 if (prefh <> nil) & (GetHandleSize(prefh) < 4) then begin { very bad! }
  769.                     RmveResource(prefh);
  770.                     DisposeHandle(prefh);
  771.                     prefh := nil;
  772.                 end;
  773.                 if (prefh = nil) then begin
  774.                     old_attr := 0;
  775.                 end
  776.                 else begin
  777.                     old_attr := longintPtr(prefh^)^;
  778.                 end;
  779.                 if attr = ICattr_no_change then begin
  780.                     attr := old_attr;
  781.                 end; (* if *)
  782.                 if btst(old_attr, ICattr_locked_bit) and btst(attr, ICattr_locked_bit) and (buf <> nil) then begin
  783.                     err := icPermErr;
  784.                 end; (* if *)
  785.                 if (prefh = nil) then begin
  786.                     prefh := NewHandle(size + 4);
  787.                     err := MemError;
  788.                     if err = noErr then begin
  789.                         repeat
  790.                             id := Unique1ID(Res_Code);
  791.                         until id > 127;
  792.                         AddResource(prefh, Res_Code, id, key);
  793.                         err := ResError;
  794.                         if err <> noErr then begin
  795.                             DisposeHandle(prefh);
  796.                             prefh := nil;
  797.                         end; (* if *)
  798.                     end; (* if *)
  799.                 end; (* if *)
  800.                 if (err = noErr) & (buf <> nil) then begin
  801.                     SetHandleSize(prefh, size + 4);
  802.                     err := MemError;
  803.                 end; (* if *)
  804.                 if (err = noErr) & (size > 0) then begin
  805.                     BlockMove(buf, ptr(longint(prefh^) + 4), size);
  806.                 end; (* if *)
  807.                 if (err = noErr) then begin
  808.                     longintPtr(prefh^)^ := attr;
  809.                     ChangedResource(prefh);
  810.                     WriteResource(prefh);
  811.                     err := ResError;
  812.                 end; (* if *)
  813.                 UseResFile(old_refnum);
  814.             end; (* if *)
  815.         end; (* if *)
  816.         if prefh <> nil then begin
  817.             ReleaseResource(prefh);
  818.         end; (* if *)
  819.         err2 := ICRReleaseInside(inst, force_info);
  820.         if err = noErr then begin
  821.             err := err2;
  822.         end; (* if *)
  823.         ICRSetPref := err;
  824.     end; (* ICRSetPref *)
  825.  
  826.     (* I call ICRForceInside to speed this routine up.  ICRForceInside will do an ICRBegin and hence open the resource *)
  827.     (* file, which is good because otherwise I'd open it twice, once for each ICRGetPref. *)
  828.  
  829.     function ICRFindPrefHandle (var inst: ICRRecord; key: Str255; var attr: ICAttr; prefh: Handle): ICError;
  830.         var
  831.             err: ICError;
  832.             prefsize: longint;
  833.             force_info: boolean;
  834.             err2: ICError;
  835.     begin
  836.         err := noErr;
  837.         if prefh = nil then begin
  838.             err := paramErr;
  839.         end;
  840.         prefsize := 0;
  841.         if err = noErr then begin
  842.             err := ICRForceInside(inst, icReadOnlyPerm, force_info);
  843.             if err = noErr then begin
  844.                 err := ICRGetPref(inst, key, attr, nil, prefsize);
  845.             end;
  846.             if err = noErr then begin
  847.                 SetHandleSize(prefh, prefsize);
  848.                 err := MemError;
  849.             end; (* if *)
  850.             if err = noErr then begin
  851.                 HLock(prefh);
  852.                 err := ICRGetPref(inst, key, attr, prefh^, prefsize);
  853.                 HUnlock(prefh);
  854.             end; (* if *)
  855.             err2 := ICRReleaseInside(inst, force_info);
  856.         end; (* if *)
  857.         if err = noErr then begin
  858.             err := err2;
  859.         end; (* if *)
  860.         if (prefh <> nil) and (err <> noErr) then begin
  861.             SetHandleSize(prefh, 0);
  862.         end; (* if *)
  863.         ICRFindPrefHandle := err;
  864.     end; (* ICRFindPrefHandle *)
  865.  
  866.     function ICRGetPrefHandle (var inst: ICRRecord; key: Str255; var attr: ICAttr; var prefh: Handle): ICError;
  867.         var
  868.             err: ICError;
  869.     begin
  870.         prefh := NewHandle(0);
  871.         err := MemError;
  872.         if err = noErr then begin
  873.             err := ICRFindPrefHandle(inst, key, attr, prefh);
  874.         end;
  875.         if err = icPrefNotFoundErr then begin
  876.             SetHandleSize(prefh, 0);
  877.             attr := 0;
  878.             err := noErr;
  879.         end;
  880.         ICRGetPrefHandle := err;
  881.     end;
  882.  
  883.     function ICRSetPrefHandle (var inst: ICRRecord; key: Str255; attr: ICAttr; prefh: Handle): ICError;
  884.         var
  885.             s: SignedByte;
  886.             err: ICError;
  887.     begin
  888.         err := noErr;
  889.         if prefh <> nil then begin
  890.             if prefh^ = nil then begin
  891.                 err := paramErr;
  892.             end; (* if *)
  893.             if err = noErr then begin
  894.                 s := HGetState(prefh);
  895.                 HLock(prefh);
  896.                 err := ICRSetPref(inst, key, attr, prefh^, GetHandleSize(prefh));
  897.                 HSetState(prefh, s);
  898.             end; (* if *)
  899.         end
  900.         else begin
  901.             err := ICRSetPref(inst, key, attr, nil, 0);
  902.         end; (* if *)
  903.         ICRSetPrefHandle := err;
  904.     end; (* ICRSetPrefHandle *)
  905.  
  906.     function ICRCountPref (var inst: ICRRecord; var count: longint): ICError;
  907.         var
  908.             err: ICError;
  909.             old_refnum: integer;
  910.     begin
  911.         err := ICRCheckInside(inst);
  912.         if err = noErr then begin
  913.             if inst.config_refnum = 0 then begin
  914.                 count := 0;
  915.             end
  916.             else begin
  917.                 old_refnum := CurResFile;
  918.                 UseResFile(inst.config_refnum);
  919.                 err := ResError;
  920.                 if err = noErr then begin
  921.                     count := Count1Resources(Res_Code);
  922.                     err := ResError;
  923.                     UseResFile(old_refnum);
  924.                 end; (* if *)
  925.             end; (* if *)
  926.         end; (* if *)
  927.         if err <> noErr then begin
  928.             count := 0;
  929.         end; (* if *)
  930.         ICRCountPref := err;
  931.     end; (* ICRCountPref *)
  932.  
  933.     function ICRGetIndPref (var inst: ICRRecord; n: longint; var key: Str255): ICError;
  934.         var
  935.             err: ICError;
  936.             old_refnum: integer;
  937.             prefh: Handle;
  938.             junk_id: integer;
  939.             junk_type: ResType;
  940.     begin
  941.         prefh := nil;
  942.         err := ICRCheckInside(inst);
  943.         if (err = noErr) and (n < 1) then begin
  944.             err := paramErr;
  945.         end; (* if *)
  946.         if err = noErr then begin
  947.             if inst.config_refnum = 0 then begin
  948.                 err := icPrefNotFoundErr;
  949.             end
  950.             else begin
  951.                 old_refnum := CurResFile;
  952.                 UseResFile(inst.config_refnum);
  953.                 err := ResError;
  954.                 if err = noErr then begin
  955.                     SetResLoad(false);
  956.                     prefh := Get1IndResource(Res_Code, n);
  957.                     SetResLoad(true);
  958.                     if prefh = nil then begin
  959.                         err := icPrefNotFoundErr;
  960.                     end
  961.                     else begin
  962.                         GetResInfo(prefh, junk_id, junk_type, key);
  963.                         err := ResError;
  964.                     end; (* if *)
  965.                     UseResFile(old_refnum);
  966.                 end; (* if *)
  967.             end; (* if *)
  968.         end; (* if *)
  969.         if prefh <> nil then begin
  970.             ReleaseResource(prefh);
  971.         end; (* if *)
  972.         ICRGetIndPref := err;
  973.     end; (* ICRGetIndPref *)
  974.  
  975.     function ICRDeletePref (var inst: ICRRecord; key: Str255): ICError;
  976.         var
  977.             err: ICError;
  978.             prefh: Handle;
  979.             old_refnum: integer;
  980.     begin
  981.         err := ICRCheckInside(inst);
  982.         if (err = noErr) and (key = '') then begin
  983.             err := paramErr;
  984.         end; (* if *)
  985.         if err = noErr then begin
  986.             if inst.config_refnum = 0 then begin
  987.                 err := icPrefNotFoundErr;
  988.             end
  989.             else begin
  990.                 old_refnum := CurResFile;
  991.                 UseResFile(inst.config_refnum);
  992.                 err := ResError;
  993.                 if err = noErr then begin
  994.                     SetResLoad(false);
  995.                     prefh := Get1NamedResource(Res_Code, key);
  996.                     err := ResError;
  997.                     SetResLoad(true);
  998.                     if prefh = nil then begin
  999.                         err := icPrefNotFoundErr;
  1000.                     end; (* if *)
  1001.                     if err = noErr then begin
  1002.                         RmveResource(prefh);
  1003.                         err := ResError;
  1004.                     end; (* if *)
  1005.                     UseResFile(old_refnum);
  1006.                 end; (* if *)
  1007.             end; (* if *)
  1008.         end; (* if *)
  1009.         ICRDeletePref := err;
  1010.     end; (* ICRDeletePref *)
  1011.  
  1012.     function ICREnd (var inst: ICRRecord): ICError;
  1013.         var
  1014.             err: ICError;
  1015.             dummy_boolean: Boolean;
  1016.     begin
  1017.         err := ICRCheckInside(inst);
  1018.         dummy_boolean := ICRCloseIfOpen(inst);
  1019.         ICREnd := err;
  1020.     end; (* ICREnd *)
  1021.  
  1022.     function ICRDefaultFileName (var inst: ICRRecord; var name: Str63): ICError;
  1023.     begin
  1024.         name := ICdefault_file_name;
  1025.         ICRDefaultFileName := noErr;
  1026.     end; (* ICRDefaultFileName *)
  1027.  
  1028.     function ICREditPreferences (var inst: ICRRecord; key: Str255): ICError;
  1029.         var
  1030.             err: ICError;
  1031.     begin
  1032.         err := noErr;
  1033.         if not inst.have_config_file then begin
  1034.             err := bdNamErr;
  1035.         end; (* if *)
  1036.         if err = noErr then begin
  1037.             err := ICUEditPreferences(key, inst.config_file);
  1038.         end; (* if *)
  1039.         ICREditPreferences := err;
  1040.     end; (* ICREditPreferences *)
  1041.  
  1042. (* URL Parsing Algorithm *)
  1043.  
  1044. {1. if there is a selection skip to step 4}
  1045. {2. expand selection to end of word (never skip a bracket though) }
  1046. {3. if either end has a bracket then expand other end to search for a matching bracket}
  1047. {4. strip trailing and leading whitespace}
  1048. {5. strip whitespace CR whitespace}
  1049. {6. take off brackets or}
  1050. {7. strip trailing "." unless there was originally a selection}
  1051. {8. remove leading URL:}
  1052. {9. extract protocol by looking forwards for :}
  1053. {10. if no protocol then prepend "hint:"}
  1054.  
  1055.     const
  1056.         verybig = 100000;
  1057.     type
  1058.         dataArray = packed array[0..verybig] of char;
  1059.         dataPtr = ^dataArray;
  1060.         dataHandle = ^dataPtr;
  1061.  
  1062.     const
  1063.         kForwardExpandTerminateSet = [' ', '<', '[', '(', '{', '"', '''', 'ヤ', 'メ', chr(9), chr(13)];
  1064.         kForwardBracketSet = ['<', '[', '(', '{', '"', '''', 'ヤ', 'メ'];
  1065.         kBackwardExpandTerminateSet = [' ', '>', ']', ')', ')', '"', '''', 'ユ', 'モ', chr(9), chr(13)];
  1066.         kBackwardBracketSet = ['>', ']', ')', '}', '"', '''', 'ユ', 'モ'];
  1067.  
  1068.     function MatchingBracket (ch: char): char;
  1069.     begin
  1070.         case ch of
  1071.             '<': 
  1072.                 MatchingBracket := '>';
  1073.             '>': 
  1074.                 MatchingBracket := '<';
  1075.             '[': 
  1076.                 MatchingBracket := ']';
  1077.             ']': 
  1078.                 MatchingBracket := '[';
  1079.             '(': 
  1080.                 MatchingBracket := ')';
  1081.             ')': 
  1082.                 MatchingBracket := '(';
  1083.             '{': 
  1084.                 MatchingBracket := '}';
  1085.             '}': 
  1086.                 MatchingBracket := '{';
  1087.             'ヤ': 
  1088.                 MatchingBracket := 'ユ';
  1089.             'ユ': 
  1090.                 MatchingBracket := 'ヤ';
  1091.             'メ': 
  1092.                 MatchingBracket := 'モ';
  1093.             'モ': 
  1094.                 MatchingBracket := 'メ';
  1095.             otherwise
  1096.                 MatchingBracket := ch;
  1097.         end; (* case *)
  1098.     end; (* MatchingBracket *)
  1099.  
  1100.     function ExpandSelection (datap: dataPtr; len: longint; var selStart, selEnd: longint): ICError;
  1101.         var
  1102.             err: ICError;
  1103.             found: boolean;
  1104.             search_char: char;
  1105.     begin
  1106.         err := noErr;
  1107.         (* expand leading selection backwards looking for word break *)
  1108.         while (selStart > 0) & not (datap^[selStart - 1] in kForwardExpandTerminateSet) do begin
  1109.             selStart := selStart - 1;
  1110.         end; (* while *)
  1111.         if (selStart > 0) & (datap^[selStart - 1] in kForwardBracketSet) then begin
  1112.             selStart := selStart - 1;
  1113.         end; (* if *)
  1114.         (* expand trailing selection forwards looking for work break *)
  1115.         while (selEnd < len) & not (datap^[selEnd] in kBackwardExpandTerminateSet) do begin
  1116.             selEnd := selEnd + 1;
  1117.         end; (* while *)
  1118.         if (selEnd < len) & (datap^[selEnd] in kBackwardBracketSet) then begin
  1119.             selEnd := selEnd + 1;
  1120.         end; (* if *)
  1121.         (* if first character was a < then expand trailing selection to meet matching > *)
  1122.         if datap^[selStart] in kForwardBracketSet then begin
  1123.             search_char := MatchingBracket(datap^[selStart]);
  1124.             found := false;
  1125.             while not found and (selEnd - 1 < len) do begin
  1126.                 found := (datap^[selEnd - 1] = search_char);
  1127.                 if not found then begin
  1128.                     selEnd := selEnd + 1;
  1129.                 end; (* if *)
  1130.             end; (* while *)
  1131.             if not found then begin
  1132.                 err := icNoURLErr;
  1133.             end; (* if *)
  1134.         end; (* if *)
  1135.         (* if last character was a > then expand leading selection to meet matching < *)
  1136.         if (err = noErr) & (selEnd > 0) & (datap^[selEnd - 1] in kBackwardBracketSet) then begin
  1137.             search_char := MatchingBracket(datap^[selEnd - 1]);
  1138.             found := (datap^[selStart] = search_char);
  1139.             while not found and (selStart >= 0) do begin
  1140.                 found := (datap^[selStart] = search_char);
  1141.                 if not found then begin
  1142.                     selStart := selStart - 1;
  1143.                 end; (* if *)
  1144.             end; (* if *)
  1145.             if not found then begin
  1146.                 err := icNoURLErr;
  1147.             end; (* if *)
  1148.         end; (* if *)
  1149.         ExpandSelection := err;
  1150.     end; (* ExpandSelection *)
  1151.  
  1152.     function ShrinkSelection (datap: dataPtr; len: longint; var selStart, selEnd: longint): ICError;
  1153.     begin
  1154.         (* strip leading whitespace *)
  1155.         while (selStart < len) & (datap^[selStart] in [' ', chr(9)]) do begin
  1156.             selStart := selStart + 1;
  1157.         end; (* while *)
  1158.         (* strip trailing whitespace *)
  1159.         while (selEnd > 0) & (datap^[selEnd - 1] in [' ', chr(9)]) do begin
  1160.             selEnd := selEnd - 1;
  1161.         end; (* while *)
  1162.         ShrinkSelection := noErr;
  1163.     end; (* ShrinkSelection *)
  1164.  
  1165.     function StripReturns (urlh: dataHandle): ICError;
  1166.             (* removes any sequence of <whitespace> <cr> <whitespace> from urlh *)
  1167.         var
  1168.             srcsize: longint;
  1169.             srcndx: longint;
  1170.             dstndx: longint;
  1171.             err: ICError;
  1172.     begin
  1173.         srcsize := GetHandleSize(Handle(urlh));
  1174.         srcndx := 0;
  1175.         dstndx := 0;
  1176.             (* skip down the handle copying src to dst except when meeting cr *)
  1177.         while srcndx < srcsize do begin
  1178.             if urlh^^[srcndx] = chr(13) then begin
  1179.                     (* move dstndx back to point to previous non-whitespace *)
  1180.                 while (dstndx > 0) & (urlh^^[dstndx - 1] in [' ', chr(9)]) do begin
  1181.                     dstndx := dstndx - 1;
  1182.                 end; (* while *)
  1183.                     (* move srcndx forwards to next non-whitespace *)
  1184.                 while (srcndx < srcsize) & (urlh^^[srcndx] in [' ', chr(9), chr(13)]) do begin
  1185.                     srcndx := srcndx + 1;
  1186.                 end; (* while *)
  1187.             end; (* case *)
  1188.             if srcndx < srcsize then begin
  1189.                     (* copy a byte from src to dst *)
  1190.                 urlh^^[dstndx] := urlh^^[srcndx];
  1191.                 srcndx := srcndx + 1;
  1192.                 dstndx := dstndx + 1;
  1193.             end; (* if *)
  1194.         end; (* while *)
  1195.             (* resize the handle to the number of bytes that we copied *)
  1196.         SetHandleSize(Handle(urlh), dstndx);
  1197.         err := MemError;
  1198.         if (err = noErr) & (GetHandleSize(Handle(urlh)) = 0) then begin
  1199.             err := icNoURLErr;
  1200.         end; (* if *)
  1201.         StripReturns := err;
  1202.     end; (* StripReturns *)
  1203.  
  1204.     function ICRParseURL (var inst: ICRRecord; hint: Str255; data: Ptr; len: longint; var selStart: longint; var selEnd: longint; url: Handle): ICError;
  1205.         var
  1206.             datap: dataPtr;
  1207.             urlh: dataHandle;
  1208.             tmp: Str15;
  1209.             junklong: longint;
  1210.             ndx: longint;
  1211.             err: ICError;
  1212.             explicit_selection: Boolean;
  1213.     begin
  1214.         datap := dataPtr(data);
  1215.         urlh := dataHandle(url);
  1216.         err := noErr;
  1217.         explicit_selection := true;
  1218.         if (data = nil) | (url = nil) | (url^ = nil) | (len <= 0) | (selStart < 0) | (selEnd < 0) | (selStart > len) | (selEnd > len) | (selStart > selEnd) then begin
  1219.             err := paramErr;
  1220.         end; (* if *)
  1221.         if (err = noErr) and (selStart = selEnd) then begin
  1222.             explicit_selection := false;
  1223.             err := ExpandSelection(datap, len, selStart, selEnd);
  1224.         end; (* if *)
  1225.         if err = noErr then begin
  1226.             (* remove leading and trailing whitespace sequences *)
  1227.             err := ShrinkSelection(datap, len, selStart, selEnd);
  1228.         end; (* if *)
  1229.         if (err = noErr) and (selStart >= selEnd) then begin
  1230.             err := icNoURLErr;
  1231.         end; (* if *)
  1232.         if err = noErr then begin
  1233.             (* copy the selection out into url *)
  1234.             err := PtrToXHand(@datap^[selStart], url, selEnd - selStart);
  1235.         end; (* if *)
  1236.         if err = noErr then begin
  1237.             (* remove any <whitespace> <cr> <whitespace> sequences *)
  1238.             err := StripReturns(urlh);
  1239.         end; (* if *)
  1240.         if err = noErr then begin
  1241.             (* trim any enclosing < > *)
  1242.             if (urlh^^[0] in kForwardBracketSet) & (urlh^^[GetHandleSize(Handle(urlh)) - 1] = MatchingBracket(urlh^^[0])) then begin
  1243.                 SetHandleSize(Handle(urlh), GetHandleSize(Handle(urlh)) - 1);        (* trim off tail *)
  1244.                 junklong := Munger(Handle(urlh), 0, nil, 1, Ptr(-1), 0);    (* trim off first character *)
  1245.             end
  1246.             else if not explicit_selection then begin
  1247.                 (* remove trailing "." if there was no explicit selection *)
  1248.                 if urlh^^[GetHandleSize(Handle(urlh)) - 1] = '.' then begin
  1249.                     SetHandleSize(Handle(urlh), GetHandleSize(Handle(urlh)) - 1);        (* trim off last character *)
  1250.                 end; (* if *)
  1251.             end; (* if *)
  1252.             (* trim off leading "URL:" *)
  1253.             tmp := 'URL:';
  1254.             HLock(Handle(urlh));
  1255.             if (GetHandleSize(Handle(urlh)) >= length(tmp)) & (IUMagIDString(Ptr(urlh^), @tmp[1], length(tmp), length(tmp)) = 0) then begin
  1256.                 HUnlock(Handle(urlh));        (* unlock 'cause Munger is going to want it that way *)
  1257.                 junklong := Munger(Handle(urlh), 0, nil, length(tmp), Ptr(-1), 0);    (* trim off 'URL:' character *)
  1258.             end;
  1259.             HUnlock(Handle(urlh));
  1260.             (* search for protocol *)
  1261.             tmp := ':';
  1262.             ndx := Munger(Handle(urlh), 0, @tmp[1], length(tmp), nil, 0);
  1263.             if (ndx < 0) or (ndx > 255) then begin
  1264.                 (* failed to find : in first 256 bytes, prepend "hint:" to URL *)
  1265.                 if hint = '' then begin
  1266.                     err := icNoURLErr;
  1267.                 end
  1268.                 else begin
  1269.                     hint := concat(hint, ':');
  1270.                     junklong := Munger(Handle(urlh), 0, nil, 0, @hint[1], length(hint));
  1271.                     err := MemError;
  1272.                 end; (* if *)
  1273.             end; (* if *)
  1274.         end; (* if *)
  1275.         ICRParseURL := err;
  1276.     end; (* ICRParseURL *)
  1277.  
  1278.     function ICRLaunchURL (var inst: ICRRecord; hint: Str255; data: Ptr; len: longint; var selStart: longint; var selEnd: longint): ICError;
  1279.         var
  1280.             err: ICError;
  1281.             urlh: Handle;
  1282.             helper: ICAppSpec;
  1283.             scheme: Str255;
  1284.             junk_attr: longint;
  1285.             size: longint;
  1286.     begin
  1287.         urlh := NewHandle(0);
  1288.         err := MemError;
  1289.         if err = noErr then begin
  1290.             err := ICRParseURL(inst, hint, data, len, selStart, selEnd, urlh);
  1291.         end; (* if *)
  1292.         if err = noErr then begin
  1293.             err := ICUFindScheme(urlh, scheme);
  1294.         end; (* if *)
  1295.         if err = noErr then begin
  1296.             size := sizeof(helper);
  1297.             err := ICRGetPref(inst, concat(kICHelper, scheme), junk_attr, @helper, size);
  1298.         end; (* if *)
  1299.         if err = noErr then begin
  1300.             err := ICULaunchURL(helper.fCreator, urlh);
  1301.         end; (* if *)
  1302.         if urlh <> nil then begin
  1303.             DisposeHandle(urlh);
  1304.         end; (* if *)
  1305.         ICRLaunchURL := err;
  1306.     end; (* ICRLaunchURL *)
  1307.  
  1308. (* Internal Mapping Subsハ*)
  1309.  
  1310.     function UnpackEntry (entries: handle; pos: longInt; var entry: ICMapEntry; var user_length: longInt): OSErr;
  1311. (* WARNING: Depends very much on the exact format of ICMapEntry! *)
  1312.         procedure CopyString (var p: ptr; var s: str255);
  1313.             var
  1314.                 len: integer;
  1315.         begin
  1316.             len := BAND(p^, $FF) + 1;
  1317.             BlockMove(p, @s, len);
  1318.             p := ptr(ord(p) + len);
  1319.         end;
  1320.         var
  1321.             org: Ptr;
  1322.             p: ptr;
  1323.             maxsize: longInt;
  1324.             err: OSErr;
  1325.     begin
  1326.         err := noErr;
  1327.         if (entries = nil) | (entries^ = nil) | (pos < 0) | (pos > GetHandleSize(entries) - 6) then begin
  1328.             err := paramErr;
  1329.         end;
  1330.         if err = noErr then begin
  1331.             p := (ptr(ord(entries^) + pos));
  1332.             maxsize := GetHandleSize(entries);
  1333.             org := p;
  1334.             BlockMove(p, @entry, 6);
  1335.             if (entry.fixed_length <> ICmap_fixed_length) | (entry.fixed_length > entry.total_length) | (entry.total_length > maxsize) then begin
  1336.                 err := badExtResource;
  1337.             end;
  1338.         end;
  1339.         if err = noErr then begin
  1340.             BlockMove(p, @entry, entry.fixed_length);
  1341.             p := ptr(ord(p) + entry.fixed_length);
  1342.             CopyString(p, entry.extension);
  1343.             CopyString(p, entry.creator_app_name);
  1344.             CopyString(p, entry.post_app_name);
  1345.             CopyString(p, entry.MIME_type);
  1346.             CopyString(p, entry.entry_name);
  1347.             user_length := entry.total_length - (ord(p) - ord(org));
  1348.         end;
  1349.         UnpackEntry := err;
  1350.     end;
  1351.  
  1352.     function FastGetEntry (entries: Handle; pos: longint; var entry: ICMapEntry): OSErr;
  1353. (* A fast version of ICRGetEntry, doesn't return all of the strings in the entry. *)
  1354. (* WARNING: Depends very much on the exact format of ICMapEntry! *)
  1355.         var
  1356.             org: Ptr;
  1357.             p: ptr;
  1358.             maxsize: longInt;
  1359.             err: OSErr;
  1360.     begin
  1361.         err := noErr;
  1362.         if (entries = nil) | (entries^ = nil) | (pos < 0) | (pos > GetHandleSize(entries) - 6) then begin
  1363.             err := paramErr;
  1364.         end;
  1365.         if err = noErr then begin
  1366.             p := (ptr(ord(entries^) + pos));
  1367.             maxsize := GetHandleSize(entries);
  1368.             BlockMove(p, @entry, 6);
  1369.             if (entry.fixed_length <> ICmap_fixed_length) | (entry.fixed_length > entry.total_length) | (entry.total_length > maxsize) then begin
  1370.                 err := badExtResource;
  1371.             end;
  1372.         end;
  1373.         if err = noErr then begin
  1374.             BlockMove(p, @entry, entry.fixed_length);
  1375.             p := ptr(ord(p) + entry.fixed_length);
  1376.             BlockMove(p, @entry.extension, band(p^, $00FF) + 1);
  1377.         end;
  1378.         FastGetEntry := err;
  1379.     end; (* FastGetEntry *)
  1380.  
  1381.     procedure PackEntry (var entry: ICMapEntry; p: ptr; user_length: longInt);
  1382.         procedure CopyString (var s: str255);
  1383.         begin
  1384.             BlockMove(@s, ptr(ord(p) + entry.total_length), length(s) + 1);
  1385.             entry.total_length := entry.total_length + length(s) + 1;
  1386.         end;
  1387.     begin
  1388.         entry.version := 0;
  1389.         entry.fixed_length := ord(@entry.extension) - ord(@entry);
  1390.         entry.total_length := entry.fixed_length;
  1391.         CopyString(entry.extension);
  1392.         CopyString(entry.creator_app_name);
  1393.         CopyString(entry.post_app_name);
  1394.         CopyString(entry.MIME_type);
  1395.         CopyString(entry.entry_name);
  1396.         entry.total_length := entry.total_length + user_length;
  1397.         BlockMove(@entry, p, entry.fixed_length);
  1398.     end;
  1399.  
  1400.     function GetShort (p: Ptr): integer;
  1401.     begin
  1402.         GetShort := BAND(p^, $FF) * 256 + BAND(ptr(ord(p) + 1)^, $FF);
  1403.     end;
  1404.  
  1405.     function UpCase (ch: char): char;
  1406.     inline
  1407.         $301F, $0C00, $0061, $6500, $000E, $0C00, $007B, $6400, $0006, $0400, $0020, $3E80;
  1408.  
  1409.     function IsExtensionVar (var name, ext: str255): boolean;
  1410.         var
  1411.             pn, pe: integer;
  1412.     begin
  1413.         IsExtensionVar := false;
  1414.         if length(name) >= length(ext) then begin
  1415.             pn := length(name) - length(ext) + 1;
  1416.             pe := 1;
  1417.             while pe <= length(ext) do begin
  1418.                 if UpCase(name[pn]) <> UpCase(ext[pe]) then begin
  1419.                     leave;
  1420.                 end; (* if *)
  1421.                 pn := pn + 1;
  1422.                 pe := pe + 1;
  1423.             end; (* while *)
  1424.             IsExtensionVar := (pe > length(ext));
  1425.         end; (* if *)
  1426.     end; (* IsExtensionVar *)
  1427.  
  1428. (* Low Level Mapping Routines *)
  1429.  
  1430.     function ICRCountMapEntries (var inst: ICRRecord; entries: Handle; var count: longint): ICError;
  1431.         var
  1432.             err: ICError;
  1433.             p: Ptr;
  1434.             pos: longint;
  1435.             size: integer;
  1436.     begin
  1437.         err := noErr;
  1438.         if (entries = nil) | (entries^ = nil) then begin
  1439.             err := paramErr;
  1440.         end; (* if *)
  1441.         if err = noErr then begin
  1442.             p := entries^;
  1443.             pos := 0;
  1444.             count := 0;
  1445.             while pos < GetHandleSize(entries) do begin
  1446.                 size := GetShort(p);
  1447.                 pos := pos + size;
  1448.                 p := ptr(ord(p) + size);
  1449.                 count := count + 1;
  1450.             end; (* while *)
  1451.         end; (* if *)
  1452.         ICRCountMapEntries := err;
  1453.     end; (* ICRCountMapEntries *)
  1454.  
  1455.     function ICRGetIndMapEntry (var inst: ICRRecord; entries: handle; ndx: longint; var pos: longint; var entry: ICMapEntry): ICError;
  1456.         var
  1457.             err: ICError;
  1458.             p: Ptr;
  1459.             i: longint;
  1460.             size: integer;
  1461.     begin
  1462.         err := noErr;
  1463.         if (entries = nil) | (entries^ = nil) | (ndx < 0) then begin
  1464.             err := paramErr;
  1465.         end; (* if *)
  1466.         if err = noErr then begin
  1467.             p := entries^;
  1468.             pos := 0;
  1469.             while (ndx > 1) & (pos < GetHandleSize(entries)) do begin
  1470.                 size := GetShort(p);
  1471.                 pos := pos + size;
  1472.                 p := Ptr(ord(p) + size);
  1473.                 ndx := ndx - 1;
  1474.             end; (* while *)
  1475.             err := ICRGetMapEntry(inst, entries, pos, entry);
  1476.         end; (* if *)
  1477.         ICRGetIndMapEntry := err;
  1478.     end; (* ICRGetIndMapEntry *)
  1479.  
  1480.     function ICRGetMapEntry (var inst: ICRRecord; entries: handle; pos: longInt; var entry: ICMapEntry): ICError;
  1481.         var
  1482.             err: ICError;
  1483.             user_length: longInt;
  1484.     begin
  1485.         err := noErr;
  1486.         if (entries = nil) | (entries^ = nil) | (pos < 0) | (pos >= GetHandleSize(entries)) then begin
  1487.             err := paramErr;
  1488.         end; (* if *)
  1489.         if err = noErr then begin
  1490.             err := UnpackEntry(entries, pos, entry, user_length);
  1491.         end; (* if *)
  1492.         ICRGetMapEntry := err;
  1493.     end; (* ICRGetMapEntry *)
  1494.  
  1495.     function ICRSetMapEntry (var inst: ICRRecord; entries: handle; pos: longInt; var entry: ICMapEntry): ICError;
  1496.         var
  1497.             err: ICError;
  1498.             e: ICMapEntry;
  1499.             oldentry: ICMapEntry;
  1500.             user_length: longInt;
  1501.             source_length: longInt;
  1502.             junk: longInt;
  1503.     begin
  1504.         err := noErr;
  1505.         if (entries = nil) | (entries^ = nil) | (pos < 0) | (pos >= GetHandleSize(entries)) then begin
  1506.             err := paramErr;
  1507.         end; (* if *)
  1508.         if err = noErr then begin
  1509.             err := UnpackEntry(entries, pos, oldentry, user_length);
  1510.         end; (* if *)
  1511.         if err = noErr then begin
  1512.             PackEntry(entry, @e, user_length);
  1513.             source_length := oldentry.total_length - user_length;
  1514.             if user_length < 8 then begin { hack to remove alignment bytes from previous version }
  1515.                 source_length := oldentry.total_length;
  1516.                 e.total_length := e.total_length - user_length;
  1517.                 user_length := 0;
  1518.             end;
  1519.             junk := Munger(entries, pos, nil, source_length, @e, e.total_length - user_length);
  1520.             err := MemError;
  1521.         end;
  1522.         ICRSetMapEntry := err;
  1523.     end; (* ICRSetMapEntry *)
  1524.  
  1525.     function ICRDeleteMapEntry (var inst: ICRRecord; entries: handle; pos: longint): ICError;
  1526.         var
  1527.             err: ICError;
  1528.             entry: ICMapEntry;
  1529.             junk: longint;
  1530.             user_length: longInt;
  1531.     begin
  1532.         err := noErr;
  1533.         if (entries = nil) | (entries^ = nil) | (pos < 0) | (pos >= GetHandleSize(entries)) then begin
  1534.             err := paramErr;
  1535.         end; (* if *)
  1536.         if err = noErr then begin
  1537.             err := UnpackEntry(entries, pos, entry, user_length);
  1538.         end; (* if *)
  1539.         if err = noErr then begin
  1540.             junk := Munger(entries, pos, nil, entry.total_length, Ptr(-1), 0);
  1541.             err := MemError;
  1542.         end;
  1543.         ICRDeleteMapEntry := err;
  1544.     end; (* ICRDeleteMapEntry *)
  1545.  
  1546.     function ICRAddMapEntry (var inst: ICRRecord; entries: handle; var entry: ICMapEntry): ICError;
  1547.         var
  1548.             err: ICError;
  1549.             tmp_entry: ICMapEntry;
  1550.     begin
  1551.         err := noErr;
  1552.         if (entries = nil) | (entries^ = nil) then begin
  1553.             err := paramErr;
  1554.         end; (* if *)
  1555.         if err = noErr then begin
  1556.             PackEntry(entry, @tmp_entry, 0);
  1557.             err := PtrAndHand(@tmp_entry, entries, entry.total_length);
  1558.         end; (* if *)
  1559.         ICRAddMapEntry := err;
  1560.     end; (* ICRAddMapEntry *)
  1561.  
  1562. (* High Level Mapping Subs *)
  1563.  
  1564.     function ICRMapEntriesFilename (var inst: ICRRecord; entries: Handle; filename: Str255; var entry: ICMapEntry): ICError;
  1565.         (* implementation lifted directly from Space Aliens *)
  1566.         var
  1567.             err: ICError;
  1568.             longest_len: integer;
  1569.             posndx: longint;
  1570.             found_pos: longint;
  1571.     begin
  1572.         err := noErr;
  1573.         if (entries = nil) | (entries^ = nil) | (filename = '') then begin
  1574.             err := paramErr;
  1575.         end; (* if *)
  1576.         if err = noErr then begin
  1577.             (* loop through the entries *)
  1578.             (* looking for the longest match *)
  1579.             longest_len := 0;
  1580.             posndx := 0;
  1581.             while FastGetEntry(entries, posndx, entry) = noErr do begin
  1582.                 (* the entry matches if *)
  1583.                 (* not_incoming flag bit is clear *)
  1584.                 (* it's longer than the previous max *)
  1585.                 (* it's longer than the file name *)
  1586.                 (* it matches the last N chars of the filename *)
  1587.                 if (length(entry.extension) > longest_len) & not btst(entry.flags, ICmap_not_incoming_bit) & IsExtensionVar(filename, entry.extension) then begin
  1588.                     (* record the new longest entry *)
  1589.                     found_pos := posndx;
  1590.                     longest_len := length(entry.extension);
  1591.                 end; (* if *)
  1592.                 (* increment posndx so that we get the next *)
  1593.                 (* entry the next time around the loop *)
  1594.                 posndx := posndx + entry.total_length;
  1595.             end; (* while *)
  1596.         end; (* if *)
  1597.         if (err = noErr) & (longest_len = 0) then begin
  1598.             err := icPrefNotFoundErr;
  1599.         end; (* if *)
  1600.         if (err = noErr) then begin
  1601.             err := ICRGetMapEntry(inst, entries, found_pos, entry);
  1602.         end; (* if *)
  1603.         ICRMapEntriesFilename := err;
  1604.     end; (* ICRMapEntriesFilename *)
  1605.  
  1606.     function ICRMapEntriesTypeCreator (var inst: ICRRecord; entries: Handle; fType: OSType; fCreator: OSType; filename: Str255; var entry: ICMapEntry): ICError;
  1607.         var
  1608.             err: ICError;
  1609.             posndx: longint;
  1610.             found_pos: longint;
  1611.             match_weight: longint;
  1612.             best_weight: longint;
  1613.     begin
  1614.         err := noErr;
  1615.         if (entries = nil) | (entries^ = nil) then begin
  1616.             err := paramErr;
  1617.         end; (* if *)
  1618.         if err = noErr then begin
  1619.             posndx := 0;
  1620.             best_weight := -1;
  1621.             while FastGetEntry(entries, posndx, entry) = noErr do begin
  1622.                 if not btst(entry.flags, ICmap_not_outgoing_bit) then begin
  1623.                     if entry.file_type = fType then begin
  1624.                         match_weight := ord(entry.file_creator = fCreator);
  1625.                         if IsExtensionVar(filename, entry.extension) then begin
  1626.                             match_weight := match_weight + 2 * length(entry.extension);
  1627.                         end; (* if *)
  1628.                         if match_weight > best_weight then begin
  1629.                             (* record the new longest entry *)
  1630.                             found_pos := posndx;
  1631.                             best_weight := match_weight;
  1632.                         end; (* if *)
  1633.                     end; (* if *)
  1634.                 end; (* if *)
  1635.                 posndx := posndx + entry.total_length;
  1636.             end; (* while *)
  1637.             if best_weight = -1 then begin
  1638.                 err := icPrefNotFoundErr;
  1639.             end
  1640.             else begin
  1641.                 err := ICRGetMapEntry(inst, entries, found_pos, entry);
  1642.             end; (* if *)
  1643.         end; (* if *)
  1644.         ICRMapEntriesTypeCreator := err;
  1645.     end; (* ICRMapEntriesTypeCreator *)
  1646.  
  1647. (* High Level Mapping Routinesハ*)
  1648.  
  1649.     function ICRMapFilename (var inst: ICRRecord; filename: Str255; var entry: ICMapEntry): ICError;
  1650.         var
  1651.             err: ICError;
  1652.             entries: Handle;
  1653.             junk_attr: ICAttr;
  1654.     begin
  1655.         err := noErr;
  1656.         if filename = '' then begin
  1657.             err := paramErr;
  1658.         end; (* if *)
  1659.         if err = noErr then begin
  1660.             err := ICRGetPrefHandle(inst, kICMapping, junk_attr, entries);
  1661.         end; (* if *)
  1662.         if err = noErr then begin
  1663.             err := ICRMapEntriesFilename(inst, entries, filename, entry);
  1664.             DisposeHandle(entries);
  1665.         end; (* if *)
  1666.         ICRMapFilename := err;
  1667.     end; (* ICRMapFilename *)
  1668.  
  1669.     function ICRMapTypeCreator (var inst: ICRRecord; fType: OSType; fCreator: OSType; filename: Str255; var entry: ICMapEntry): ICError;
  1670.         var
  1671.             err: ICError;
  1672.             entries: Handle;
  1673.             junk_attr: ICAttr;
  1674.     begin
  1675.         err := ICRGetPrefHandle(inst, kICMapping, junk_attr, entries);
  1676.         if err = noErr then begin
  1677.             err := ICRMapEntriesTypeCreator(inst, entries, fType, fCreator, filename, entry);
  1678.             DisposeHandle(entries);
  1679.         end; (* if *)
  1680.         ICRMapTypeCreator := err;
  1681.     end; (* ICRMapTypeCreator *)
  1682.  
  1683. end. (* ICLinkIn *)